package com.koushikdutta.ion;

import com.example.ohosasynclibrary.async.future.Future;
import com.example.ohosasynclibrary.async.future.FutureCallback;
import com.example.ohosasynclibrary.async.future.SimpleFuture;
import com.example.ohosasynclibrary.async.future.TransformFuture;
import com.koushikdutta.ion.future.ImageViewFuture;
import ohos.agp.animation.Animator;
import ohos.agp.components.Image;
import ohos.agp.components.element.Element;

class ImageViewFutureImpl extends TransformFuture<Image, IonDrawable> implements ImageViewFuture {
    public static final ImageViewFutureImpl FUTURE_IMAGEVIEW_NULL_URI = new ImageViewFutureImpl() {
        {
            setComplete(new NullPointerException("uri"));
        }
    };

    private ScaleMode scaleMode;
    private Animator inAnimation;
    private int inAnimationResource;
    private ContextReference.ImageViewContextReference imageViewRef;

    public static ImageViewFutureImpl getOrCreateImageViewFuture(ContextReference.ImageViewContextReference imageViewRef, IonDrawable drawable) {
        ImageViewFutureImpl ret;

        if (drawable.getLoadCallback() instanceof ImageViewFutureImpl)
            ret = (ImageViewFutureImpl) drawable.getLoadCallback();
        else ret = new ImageViewFutureImpl();

        drawable.setLoadCallback(ret);
        ret.imageViewRef = imageViewRef;
        return ret;
    }

    @Override
    protected void transform(IonDrawable result) {
        // need to make sure that the IonDrawable calling this future
        // is still needed. It may have changed if the user manually
        // called setDrawable on the ImageView, etc.
        final Image imageView = imageViewRef.get();
        // check the imageview and the activity context
        if (null != imageViewRef.isAlive() || imageView == null) {
            cancelSilently();
            return;
        }

        // 发生改变就重新加载---
//        if (imageView.getImageElement() != result) {
//            // imageview is now waiting for something else now... cancel
//            cancelSilently();
//            return;
//        }

        // retrigger the intrinsic dimension check on the drawable
        if (scaleMode != null) {
            applyScaleMode(imageView, scaleMode);
        }
        imageView.setPixelMap(result.getBitmapInfo().bitmap);
        setComplete(imageView);
    }

    @Override
    public Future<ImageViewBitmapInfo> withBitmapInfo() {
        final SimpleFuture<ImageViewBitmapInfo> ret = new SimpleFuture<ImageViewBitmapInfo>();
        setCallback(new FutureCallback<Image>() {
            @Override
            public void onCompleted(Exception e, Image result) {
                ImageViewBitmapInfo val = new ImageViewBitmapInfo();
                Element d = null;
                if (result != null)
                    d = result.getImageElement();
                if (d instanceof IonDrawable) {
                    IonDrawable id = (IonDrawable) d;
                    val.info = id.getBitmapInfo();
                }
                val.exception = e;
                val.imageView = result;
                ret.setComplete(val);
            }
        });
        ret.setParent(this);
        return ret;
    }

    public ImageViewFutureImpl setInAnimation(Animator inAnimation, int inAnimationResource) {
        this.inAnimation = inAnimation;
        this.inAnimationResource = inAnimationResource;
        return this;
    }

    public ImageViewFutureImpl setScaleMode(ScaleMode scaleMode) {
        this.scaleMode = scaleMode;
        return this;
    }

    public static void applyScaleMode(Image imageView, ScaleMode scaleMode) {
        if (scaleMode == null)
            return;
        switch (scaleMode) {
            case CenterCrop:
                imageView.setScaleMode(Image.ScaleMode.CLIP_CENTER);
                break;
            case FitCenter:
                imageView.setScaleMode(Image.ScaleMode.CENTER);
                break;
            case CenterInside:
                imageView.setScaleMode(Image.ScaleMode.INSIDE);
                break;
            case FitXY:
                imageView.setScaleMode(Image.ScaleMode.STRETCH);
                break;
        }
    }
}